<!DOCTYPE html>
<title>Stats</title>
<meta charset="utf8">
<style>

    body {
        background-color: #333;
        color: #eee;
        font-family: "helvetica neue", helvetica, arial, sans-serif;
    }

    .vmstat-charts .template {
        display: none !important;
    }

    .vmstat-charts * {
        cursor: default;
    }

    .vmstat-charts h2 {
        margin: 40px 0 0 0;
        font-weight: 300;
    }

    .vmstat-charts main {
        width: 600px;
        margin: auto;
    }

    .vmstat-charts section {
        clear: left;
    }

    .vmstat-charts .stats {
        margin: 0;
    }

    .vmstat-charts .stat {
        list-style-type: none;
        float: left;
        margin: 0;
        width: 130px;
        font-size: 12px;
    }

    .vmstat-charts .stat-name {
        display: inline-block;
        text-align: right;
        width: 50px;
        margin-right: 5px;
    }

    .vmstat-charts .stat-value {
        font-weight: bold;
    }


</style>
<script src="__PUBLIC__/assets/js/sugar-1.4.1.min.js"></script>
<script src="__PUBLIC__/assets/js/jquery.min.js"></script>
<script src="__PUBLIC__/assets/js/reconnecting-websocket.js"></script>
<script src="__PUBLIC__/assets/js/smoothie.js"></script>
<script src="__PUBLIC__/assets/js/chroma.min.js"></script>
<script>
    var allTimeSeries = {};
    var allValueLabels = {};
    var descriptions = {
        'Processes': {
            'r': 'Number of processes waiting for run time',
            'b': 'Number of processes in uninterruptible sleep'
        },
        'Memory': {
            'swpd': 'Amount of virtual memory used',
            'free': 'Amount of idle memory',
            'buff': 'Amount of memory used as buffers',
            'cache': 'Amount of memory used as cache'
        },
        'Swap': {
            'si': 'Amount of memory swapped in from disk',
            'so': 'Amount of memory swapped to disk'
        },
        'IO': {
            'bi': 'Blocks received from a block device (blocks/s)',
            'bo': 'Blocks sent to a block device (blocks/s)'
        },
        'System': {
            'in': 'Number of interrupts per second, including the clock',
            'cs': 'Number of context switches per second'
        },
        'CPU': {
            'us': 'Time spent running non-kernel code (user time, including nice time)',
            'sy': 'Time spent running kernel code (system time)',
            'id': 'Time spent idle',
            'wa': 'Time spent waiting for IO'
        }
    };

    function streamStats() {

        var ws = new ReconnectingWebSocket("ws://{{host}}:2000");
        var colHeadings = [
            'r',
            'b',
            'swpd',
            'free',
            'buff',
            'cache',
            'si',
            'so',
            'bi',
            'bo',
            'in',
            'cs',
            'us',
            'sy',
            'id',
            'wa'
        ];

        ws.onopen = function () {
            console.log('connect');
        };

        ws.onclose = function () {
            console.log('disconnect');
        };

        ws.onmessage = function (e) {
            var colValues = e.data.trim().split(/ +/);
            var stats = {};
            for (var i = 0; i < colHeadings.length; i++) {
                stats[colHeadings[i]] = parseInt(colValues[i]);
            }
            receiveStats(stats);
        };
    }

    function initCharts() {
        Object.each(descriptions, function (sectionName, values) {
            var section = $('.chart.template').clone().removeClass('template').appendTo('#charts');

            section.find('.title').text(sectionName);

            var smoothie = new SmoothieChart({
                grid: {
                    sharpLines: true,
                    verticalSections: 5,
                    strokeStyle: 'rgba(119,119,119,0.45)',
                    millisPerLine: 1000
                },
                minValue: 0,
                labels: {
                    disabled: true
                }
            });
            smoothie.streamTo(section.find('canvas').get(0), 1000);

            var colors = chroma.brewer['Pastel2'];
            var index = 0;
            Object.each(values, function (name, valueDescription) {
                var color = colors[index++];

                var timeSeries = new TimeSeries();
                smoothie.addTimeSeries(timeSeries, {
                    strokeStyle: color,
                    fillStyle: chroma(color).darken().alpha(0.5).css(),
                    lineWidth: 3
                });
                allTimeSeries[name] = timeSeries;

                var statLine = section.find('.stat.template').clone().removeClass('template').appendTo(section.find('.stats'));
                statLine.attr('title', valueDescription).css('color', color);
                statLine.find('.stat-name').text(name);
                allValueLabels[name] = statLine.find('.stat-value');
            });
        });
    }

    function receiveStats(stats) {
        Object.each(stats, function (name, value) {
            var timeSeries = allTimeSeries[name];
            if (timeSeries) {
                timeSeries.append(Date.now(), value);
                allValueLabels[name].text(value);
            }
        });
    }

    $(function () {
        initCharts();
        streamStats();
    });

</script>

<main id="charts" class="vmstat-charts">
    <section class="chart template">
        <h2 class="title"></h2>
        <canvas width="600" height="80"></canvas>
        <ul class="stats">
            <li class="stat template">
                <span class="stat-name"></span>
                <span class="stat-value"></span>
            </li>
        </ul>
    </section>
</main>
